<template>
    <!-- 三级列表 -->
    <Category :disables="isShowList"/>

    
    <el-card shadow="always" :body-style="{ padding: '20px' }" :style="{ marginTop: '40px' }">
        <!-- 商品属性列表 -->
        <template #header v-if="!isShowList">
            <el-button :disabled="!category3Id" type="success" size="default" @click="addAttr" :icon="ElemeFilled">添加</el-button>
        </template>
        <el-table border stripe :data="tableDate" v-if="!isShowList">
            <el-table-column type="index" width="150" label="序号" align="center" />
            <el-table-column label="属性名称" width="150" prop="attrName"></el-table-column>
            <el-table-column label="属性值名称列表">
                <template #="{row}">
                    <el-tag 
                        type="success" 
                        size="deafult" 
                        v-for="item in row.attrValueList"
                        :key="item.id"
                    >{{item.valueName}}</el-tag>
                </template>
            </el-table-column>
            <el-table-column label="操作" width="150">
                <template #="{row}">
                    <el-button type="warning" size="default" :icon="Edit" @click="updateAttr(row)" ></el-button>
                    <!-- 气泡确认框 -->
                    <el-popconfirm title="你确定删除吗?" @confirm="deleteAttr(row.id)">
                            <template #reference>
                                <el-button type="danger" size="default" :icon="Failed" ></el-button>
                            </template>
                    </el-popconfirm>
                </template>
            </el-table-column>
        </el-table>

        <!-- 添加或修改商品属性 -->
        <div v-else>
            <!-- 属性名输入框 -->
            <el-form :inline="true" >
                <el-form-item label="属性名">
                    <el-input label="请输入属性名" v-model="newAttr.attrName"></el-input>
                </el-form-item>
            </el-form>
            <!-- 添加属性值和取消按钮 -->
            <div>
                <el-button :disabled="!newAttr.attrName" type="primary"  @click="addAttrValue">添加属性值</el-button>
                <el-button  @click="isShowList = false">取消</el-button>
            </div>
            <!-- 商品属性值表格 -->
            <el-table :data="newAttr.attrValueList" border stripe :style="{marginTop: '30px' , marginBottom: '30px'}">
                <el-table-column type="index" width="100" align="center" label="序号"/>
                <el-table-column label="属性值名称">
                    <template #="{row , $index}">
                        <span
                            @click="toEdit(row)"
                            :style="{display: 'inline-block' , width: '80%'}"
                            v-if="!row.isEdit"
                        >{{row.valueName}}</span>
                        <el-input
                            v-else 
                            ref="inputEle"
                            @focus="getoldAttrValueName(row)"
                            v-model="row.valueName" 
                            @blur="toLook(row , $index)"
                        ></el-input>
                    </template>
                </el-table-column>
                <el-table-column label="操作">
                    <template #="{$index}">
                        <!-- 气泡确认框 -->
                        <el-popconfirm title="你确定删除吗?" @confirm="deleteAttrValue($index)">
                            <template #reference>
                                <el-button type="danger" icon="ele-Delete"></el-button>
                            </template>
                        </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
            <!-- 保存和取消按钮 -->
            <div>
                <el-button 
                    :disabled="newAttr.attrValueList.length<=0 ||  !newAttr.attrName" type="primary"  
                    @click="addOrUpdateAttr"
                >保存</el-button>
                <el-button  @click="isShowList = false">取消</el-button>
            </div>
        </div>

    </el-card>

</template>

<script lang="ts">
import { defineComponent } from "vue";
import { storeToRefs } from "pinia";
import { ElMessage } from "element-plus";

export default defineComponent({
    name: "Attr",
});
</script>
<script setup lang="ts">
import { ElemeFilled, Edit , Failed} from "@element-plus/icons-vue"
import { nextTick, ref, watch } from "vue"
import type { reqAttrListType , reqAttrItemType , reqAttrValueType} from "@/api/attr"
import  { requestgetattrList , requestUpdateOrAddAttr , requestDeleteAttr} from "@/api/attr"
import useAttrStore from "@/stores/attr";
import  cloneDeep  from  "lodash/cloneDeep";

const attrStore = useAttrStore()
const { category1Id, category2Id, category3Id } = storeToRefs(attrStore)


//1.商品属性列表的逻辑
//定义表格数据
const tableDate = ref<reqAttrListType>([])
//封装请求商品属性列表的函数
const getAttrList = async () => {
    try {
        //请求商品属性列表
        const result = await requestgetattrList(
            category1Id.value as number,
            category2Id.value as number,
            category3Id.value as number,
        )
        //把请求回来的商品属性列表赋值给表格数据
        tableDate.value = result
    } catch (error) {
        ElMessage.error("请求商品属性列表遇到了问题...")
    }
}
//监听category3Id的改变发送请求
watch(category3Id, async(newValue) => {
    //点击一级二级，category3Id会清空为null,就把商品属性列表清空
    if(newValue === null){
        tableDate.value = []
        return
    }
    //请求商品属性列表
    getAttrList()
} , {immediate: true})


//2.添加或修改页面逻辑
//定义数据控制显示隐藏商品属性列表
const isShowList = ref(false)
//定义要添加或修改需要发送的数据
const newAttr = ref<reqAttrItemType>({
    attrName: "",
    categoryId: category3Id.value as number,
    categoryLevel: 3,
    attrValueList: []
})

//2.1点击添加的回调
const addAttr = () => {
    //显示添加和修改商品属性页面
    isShowList.value = true
    //清空页面可能残留的数据
    newAttr.value = {
        attrName: "",
        categoryId: category3Id.value as number,
        categoryLevel: 3,
        attrValueList: []
    }
}

//2.2点击修改的回调
const updateAttr = (row: reqAttrItemType) => {
    //显示添加和修改商品属性页面
    isShowList.value = true
    //拷贝一份数据
    const newRow = cloneDeep(row)
    //数据回填之前,给商品属性值数组的每一项添加一个数据,控制展示编辑状态还是查看状态
    newRow.attrValueList.forEach((item) => {
        item.isEdit = false
    })
    //数据回填
    newAttr.value = newRow
}

//获取商品属性值input元素
const inputEle = ref()
//定义旧的商品属性名称的值
let oldAttrValueName = ""
//输入框一旦获取焦点,旧取出输入框的值赋值给旧值
const getoldAttrValueName = (row: reqAttrValueType) => {
    oldAttrValueName = row.valueName
}

//2.3点击添加商品属性值的回调
const addAttrValue = () => {
    //创建一条商品属性值的数据
    const newAttrValue = ref<reqAttrValueType>({
        valueName: "", //商品属性值名称
        attrId: 0,    //商品属性id,没有也要发送
        isEdit: true  //控制添加后的属性值是编辑模式
    })
    //把数据插入商品属性值数组中
    newAttr.value.attrValueList.push(newAttrValue.value)
    //添加一条属性值后默认获取焦点 获取到旧值
    nextTick(()=>{
        inputEle.value.focus()
    })
}

//2.4点击span标签切换为编辑模式的回调
const toEdit = (row: reqAttrValueType) => {
    //切换为编辑模式
    row.isEdit = true
    //获取焦点 获取到旧值
    nextTick(() => {
        inputEle.value.focus()
    })
}

//2.5失去焦点 切换为查看模式的回调
const toLook = (row: reqAttrValueType , $index: number) => {
    //切换为查看模式
    row.isEdit = false
    
    //判断输入为空
    if(!row.valueName){
            //如果旧值也为空，说明用户输入了一个空值，我们把他删除
        if(!oldAttrValueName){
            newAttr.value.attrValueList.splice($index , 1)
        }else{
            //如果旧值不为空，说明用户把一个值删了，我们把它恢复
            row.valueName = oldAttrValueName
        }
    }

    //判断输入重复值
    const isRepeat = newAttr.value.attrValueList.some((item)=>{
        if(item === row) return
        return item.valueName === row.valueName
    })
    if(isRepeat){
        if(!oldAttrValueName){
            //如果旧值也为空，添加了一个重复的值，我们把它删除
            newAttr.value.attrValueList.splice($index , 1)
        }else{
            //如果旧值不为空，说明用户把一个值改了后和数据中重复了，我们把它恢复
            row.valueName = oldAttrValueName
        }  
    }

    //失去焦点把旧值清空
    oldAttrValueName = ""
}

//2.6点击删除属性值的回调
const deleteAttrValue = ($index: number) => {
    newAttr.value.attrValueList.splice($index , 1)
}

//2.7点击保存的回调涵数
const addOrUpdateAttr = async () => {
    try {
        //发送请求
        await requestUpdateOrAddAttr(newAttr.value)
        //成功提示
        ElMessage.success(newAttr.value.id? '修改成功!' : '添加成功!')
        //切换商品列表页
        isShowList.value = false
        //重新请求商品属性列表
        getAttrList()
    } catch (error) {
        //失败提示
        ElMessage.error(newAttr.value.id? '修改失败!' : '添加失败!')
    }
}

//2.8点击删除属性
const deleteAttr = async (id: number) => {
    try {
        //删除请求
        await requestDeleteAttr(id)
        //成功提示
        ElMessage.success("删除成功!")
        //重新请求商品属性列表
        getAttrList()
    } catch (error) {
        //失败提示
        ElMessage.error("删除失败!")
    }
}










</script>